<?php

namespace app\model;

use app\controller\v1\OutsourcingOrder;
use think\Exception;
use think\facade\Db;

class VendorsModel extends BaseModel
{
    protected $name = 'vendors';

    public const STATUS_DISABLED = 100;  //禁用
    public const STATUS_ENABLED = 200; //启用

    public const STATUS_TEXT = [
        self::STATUS_DISABLED => '禁用',
        self::STATUS_ENABLED => '启用',
    ];

    // 追加属性
    protected $append = [
        'status_text',
    ];


    public function getStatusTextAttr($value, $data)
    {
        $value = $value ?: ($data['status'] ?? '');
        return self::STATUS_TEXT[$value] ?? '';
    }


    /**
     * Notes: 外协组织列表
     * User: chenLei
     * 10/15/25 10:49:41
     * @param $params
     * @return array
     * @throws \think\db\exception\DbException
     */
    public function list($params)
    {
        $where = [];
        if (!empty($params['name'])) {
            $where[] = ['name', 'like', '%' . $params['name'] . '%'];
        }
        if (!empty($params['username'])) {
            $where[] = ['username', 'like', '%' . $params['username'] . '%'];
        }
        if (!empty($params['contact'])) {
            $where[] = ['contact', 'like', '%' . $params['contact'] . '%'];
        }
        if (!empty($params['status'])) {
            $where[] = ['status', '=', $params['status']];
        }

        return $this->where($where)->order('create_time desc')
            ->field('id,name,username,contact,phone,address,remark,status,create_time')
            ->paginate($params['page_size'] ?? 15)->toArray();
    }


    /**
     * Notes: 添加
     * User: chenLei
     * 10/15/25 10:33:52
     * @param $params
     * @return bool
     */
    public function add($params)
    {
        if ($this->where('username', $params['username'])->count()) {
            $this->error = '用户名已存在';
            return false;
        }

        $this->save([
            'company_id' => $params['company_id'],
            'name' => $params['name'],
            'username' => $params['username'],
            'password' => password_hash($params['password'], PASSWORD_BCRYPT),
            'contact' => $params['contact'],
            'phone' => $params['phone'],
            'address' => $params['address'] ?? '',
            'remark' => $params['remark'] ?? '',
            'status' => $params['status'],
        ]);

        return true;
    }


    /**
     * Notes: 编辑
     * User: chenLei
     * 10/15/25 10:40:17
     * @param $params
     * @return bool
     */
    public function edit($params)
    {
        $info = $this->where('id', $params['id'])->findOrEmpty();
        if ($info->isEmpty()) {
            $this->error = '该数据不存在';
            return false;
        }

        if ($this->where('username', $params['username'])->where('id', '<>', $params['id'])->count()) {
            $this->error = '用户名已存在';
            return false;
        }

        $data = [
            'company_id' => $params['company_id'],
            'name' => $params['name'],
            'username' => $params['username'],
            'contact' => $params['contact'],
            'address' => $params['address'] ?? '',
            'remark' => $params['remark'] ?? '',
            'status' => $params['status'],
        ];

        if (!empty($params['password'])) {
            $data['password'] = password_hash($params['password'], PASSWORD_BCRYPT);
        }

        $info->save($data);
        return true;
    }


    /**
     * Notes: 删除
     * User: chenLei
     * 10/15/25 10:43:57
     * @param $params
     * @return bool
     */
    public function del($params)
    {
        $info = $this->where('id', $params['id'])->findOrEmpty();
        if ($info->isEmpty()) {
            $this->error = '该数据不存在';
            return false;
        }

        $info->delete();
        return true;
    }


    /**
     * Notes: 修改密码
     * User: chenLei
     * 10/15/25 10:41:59
     * @param $params
     * @return bool
     */
    public function editPassword($params)
    {
        $info = $this->where('id', $params['id'])->findOrEmpty();
        if ($info->isEmpty()) {
            $this->error = '该数据不存在';
            return false;
        }

        $info->password = password_hash($params['password'], PASSWORD_BCRYPT);
        $info->save();
        return true;

    }

    /**
     * Notes: 外协登录
     * User: chenLei
     * Date: 11/3/25 10:19:54
     * @param $params
     * @return bool|string
     */
    public function login($params)
    {
        $info = $this->where('username', $params['username'])->findOrEmpty();
        if ($info->isEmpty()) {
            $this->error = '用户不存在';
            return false;
        }

        if ($info->status != self::STATUS_ENABLED) {
            $this->error = '用户被禁用';
            return false;
        }

        if (!password_verify($params['password'], $info['password'])) {
            $this->error = '用户名或密码错误';
            return false;
        }

        Db::startTrans();
        try {

            // 获取设备类型（从请求参数中获取，默认为app）
            $deviceType = $data['device_type'] ?? 'app';
            // 生成登录token (使用简单的示例，实际应该用JWT等安全方案)
            //$token = "admin-accessToken-".md5($user['id'] . time() . uniqid());
            $tokenPrefix = 'app';
            $token = $tokenPrefix . "-" . md5($info['id'] . time() . uniqid());
            // Token有效期48小时
            $expiresAt = date('Y-m-d H:i:s', time() + 48 * 3600);
            // 清理所有过期token（任意用户登录时都清理）
            $this->cleanAllExpiredTokens();
            // 根据设备类型限制token数量
            $this->limitUserTokensByDeviceType($info['id'], $deviceType);

            $insertResult = Db::name('vendors_tokens')->insert([
                'user_id' => $info['id'],
                'token' => $token,
                'device_type' => $deviceType,
                'login_time' => date('Y-m-d H:i:s'),
                'expires_at' => $expiresAt,
                'status' => 1
            ]);


            Db::commit();
        } catch (Exception $exception) {
            Db::rollback();
            $this->error = $exception->getMessage();
            return false;
        }
        $info = $info->toArray();
        $info['token'] = $token;
        unset($info['password']);
        return $info;
    }


    private function cleanAllExpiredTokens()
    {
        // 直接删除所有过期的token
        Db::name('vendors_tokens')
            ->where('expires_at', '<', date('Y-m-d H:i:s'))
            ->delete();

        // 删除所有状态为2的失效token
        Db::name('vendors_tokens')
            ->where('status', 2)
            ->delete();

        return true;
    }


    /**
     * 根据设备类型限制用户token数量
     * @param int $userId 用户ID
     * @param string $deviceType 设备类型(pc/app)
     */
    private function limitUserTokensByDeviceType($userId, $deviceType)
    {
        // 设置不同设备类型的token限制
        $maxTokens = ($deviceType === 'app') ? 1 : 2; // APP最多1个，PC最多2个

        // 获取该用户指定设备类型的有效token数量
        $tokenCount = Db::name('vendors_tokens')
            ->where('user_id', $userId)
            ->where('device_type', $deviceType)
            ->where('status', 1)
            ->count();

        // 当token数量达到限制时，删除最早的token为新token腾出空间
        if ($tokenCount >= $maxTokens) {
            $deleteCount = $tokenCount - $maxTokens + 1; // 需要删除的数量
            $oldTokens = Db::name('vendors_tokens')
                ->where('user_id', $userId)
                ->where('device_type', $deviceType)
                ->where('status', 1)
                ->order('last_active_time asc')
                ->limit($deleteCount)
                ->column('id');

            if (!empty($oldTokens)) {
                Db::name('vendors_tokens')
                    ->where('id', 'in', $oldTokens)
                    ->delete();
            }
        }
    }


    /**
     * Notes: 更新密码
     * User: chenLei
     * Date: 11/3/25 10:59:08
     * @param $params
     * @return bool
     */
    public function changePassword($params)
    {
        $info = $this->where('id', $params['user_id'])->findOrEmpty();
        if ($info->isEmpty()) {
            $this->error = '该数据不存在';
            return false;
        }
        if ($info->status != self::STATUS_ENABLED) {
            $this->error = '用户被禁用';
            return false;
        }
        if (!password_verify($params['password'], $info['password'])) {
            $this->error = '用户名或密码错误';
            return false;
        }

        $info->password = password_hash($params['new_password'], PASSWORD_BCRYPT);
        $info->save();

        return true;
    }


    /**
     * Notes: 详情
     * User: chenLei
     * Date: 11/3/25 11:23:00
     * @param $params
     * @return VendorsModel|array|false|mixed|\think\model\contract\Modelable
     */
    public function info($params)
    {
        $info = $this->where('id', $params['user_id'])->findOrEmpty();
        if ($info->isEmpty()) {
            $this->error = '该数据不存在';
            return false;
        }

        unset($info['password']);
        return $info;
    }


    /**
     * Notes: 外协订单统计f
     * User: chenLei
     * Date: 11/3/25 11:42:42
     * @param $params
     * @return array
     */
    public function orderStatistics($params)
    {

        $where = [];
        $where[] = ['vendors_id','=',$params['user_id']];

        $data['waiting_production'] = OutsourcingOrderModel::where($where)
            ->where('status', OutsourcingOrderModel::STATUS_PENDING_PRODUCTION)->count();

        $data['in_production'] = OutsourcingOrderModel::where($where)
            ->where('status', OutsourcingOrderModel::STATUS_IN_PRODUCTION)->count();

        $data['production_completed'] = OutsourcingOrderModel::where($where)
            ->where('status', OutsourcingOrderModel::STATUS_PRODUCTION_COMPLETED)->count();

        $data['confirmed_delivery'] = OutsourcingOrderModel::where($where)
            ->where('status', OutsourcingOrderModel::STATUS_DELIVERED)->count();

        return $data;

    }


    /**
     * Notes: 订单列表
     * User: chenLei
     * Date: 11/3/25 14:04:55
     * @param $params
     * @return array
     */
    public function orderList($params)
    {
        $page = $params['page'] ?? 1;
        $limit = $params['page_size'] ?? 15;

        $where = [];
        $where[] = ['o.vendors_id', '=', $params['user_id']];

        if(!empty($params['dingdan_status'])){
            $where[] = ['o.dingdan_status', '=', $params['dingdan_status']];
        }

        if(!empty($params['dingdan_code'])){
            $where[] = ['o.dingdan_code', 'like', '%'.$params['dingdan_code'].'%'];
        }

        $count = OrderModel::alias('o')->leftJoin('customer c', 'c.id = o.customer_id')
            ->where($where)->count();

        $list = OrderModel::alias('o')->leftJoin('customer c', 'c.id = o.customer_id')
            ->field('o.*,c.customer_name customer_name,c.phone1 customer_phone')
            ->where($where)
            ->order('o.id', 'desc')
            ->page($page, $limit)
            ->select()
            ->toArray();

        foreach ($list as &$item) {
            $item['sales_person'] = UserModel::where('id', $item['user_id'])->value('realname');
        }

        return ['list' => $list, 'total' => $count];
    }
}